package cz.vutbr.fit.dnacompress.alignment;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;

import org.biojava.bio.seq.io.SymbolTokenization;

import cz.vutbr.fit.dnacompress.Main;

/**
 * Abstractni trida zapouzdrujici vlastnosti zarovnavacu
 * 
 */
public abstract class AbstractAlignmentMaker {
	
	/**
	 * vysledny retezec zarovnane reference
	 */
	protected String reference = null;
	
	/**
	 * vysledny retezec zarovnane query
	 */
	protected String query = null;
	
	/**
	 * pouzity externi program
	 */
	protected String program = null;
	
	/**
	 * davka
	 */
	protected String command = null;
	
	/**
	 * nazev souboru pro vystup zarovnani
	 */
	protected String outputFileName = "";
	
	/**
	 * tokenizer DNA symbolu
	 */
	protected SymbolTokenization tokenParser;
	
	/**
	 * pracovni slozka
	 */
	protected String dataFolder = Main.dataFolder;
	
	/**
	 * @return the command
	 */
	public String getCommand() {
		return command;
	}
	/**
	 * @param command the command to set
	 */
	public void setCommand(String command) {
		this.command = command;
	}
	/**
	 * @return the outputFileName
	 */
	public String getOutputFileName() {
		return outputFileName;
	}
	/**
	 * @param outputFileName the outputFileName to set
	 */
	public void setOutputFileName(String outputFileName) {
		this.outputFileName = outputFileName;
	}
	/**
	 * @return the program
	 */
	public String getProgram() {
		return program;
	}
	/**
	 * @param program the program to set
	 */
	public void setProgram(String program) {
		this.program = program;
	}
	/**
	 * @return the reference
	 */
	public String getReference() {
		return reference;
	}
	/**
	 * @param reference the reference to set
	 */
	public void setReference(String reference) {
		this.reference = reference;
	}
	/**
	 * @return the query
	 */
	public String getQuery() {
		return query;
	}
	/**
	 * @param query the query to set
	 */
	public void setQuery(String query) {
		this.query = query;
	}
	
	
	
	/**
	 * @return the dataFolder
	 */
	public String getDataFolder() {
		return dataFolder;
	}
	
	/**
	 * @param dataFolder the dataFolder to set
	 */
	public void setDataFolder(String dataFolder) {
		this.dataFolder = dataFolder;
	}
	
	/**
	 * spusteni zarovnavani
	 *  - execute command
	 *  - parse output
	 */
	public void run() {
		
		System.out.println( "Execution of outer alignment program.");
		execute();
		//System.out.println( exitVal);
		System.out.println( "Parsing aligned data.");
		parse();
		System.out.println();
		deleteOutputFile();
	}
	
	/**
	 * spusteni prikazu
	 * 
	 * @param command
	 * @return
	 */
	public int execute( String command) {
		
		this.setCommand( command);
		return execute();
	}
	
	/**
	 * spusteni preddefinovaneho prikazu
	 * @return
	 */
	public int execute() {
		
		int exitVal = 0;
		try {
            Runtime rt = Runtime.getRuntime();
            String execComand = "cmd /c cd " + getDataFolder() + " && " + getProgram() + " " + getCommand();
            System.out.println( execComand);
            Process pr = rt.exec( execComand);

            BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));

            String line=null;
            while((line=input.readLine()) != null) {
                System.out.println(line);
            }            
            
            exitVal = pr.waitFor();
            System.out.println( "Exit value for program: " + exitVal);
            
        } catch(Exception e) {
            System.err.println(e.toString());
            e.printStackTrace();
        }
        return exitVal;
	}
	
	/**
	 * smazani vystupniho souboru zarovnani
	 * @return
	 */
	public boolean deleteOutputFile() {
		
		File output = new File(getDataFolder() + outputFileName);
		return output.delete();
	}
	
	/**
	 * Inicializace zarovnavace - povinna implementace
	 * 
	 * @param referenceFileName
	 * @param queryFileName
	 */
	abstract public void init( String referenceFileName, String queryFileName);
	
	/**
	 * parsovani vystupu - povinna implementace
	 */
	abstract public void parse();
	
}
